/*
 * Copyright 2007-2009 Perttu "celeron55" Ahola <celeron55@gmail.com>
 *
 * This file is part of jukuMagic.
 *
 * jukuMagic is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * jukuMagic is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with jukuMagic.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef MUUT_H_
#define MUUT_H_

#include <iostream>
#include <vector>
#include <string>
//#include <stdio.h>
#include <math.h>

using namespace std;

extern bool debugmessages_on;

struct Coord{
	unsigned int x, y;
	bool exist;
	Coord();
	Coord(int x_, int y_);
	bool operator == (Coord c);
	bool operator != (Coord c);
	Coord operator + (Coord c);
	string String();
};

Coord MakeCoord(unsigned int x, unsigned int y);
Coord MakeInexistentCoord();
double Distance(Coord c1, Coord c2);
double Distance(Coord c1, vector<Coord> c2);

void DumpCoords(vector<Coord> cs);

extern void Line(int x0, int y0, int x1, int y1, vector<Coord> &cs);

enum Contenttype{
	CUT,
	HOLE,
	PFOOT,
	WPFOOT,
	WIREHEAD,
	OVERBOARD,
	NOTHING,
};

struct Contentblock{
	Contenttype type;
	int num;
	string partname_blocks; //name of a part that is blocking the hole,
	                        //"" if not blocked, "this" on footprint
	int nfc_partnum; //Needed For Connection, -1 if not needed
	Contentblock();
	Contentblock(Contenttype t, int n);
	string TypeString();
};

struct Wire{
	Coord c1, c2;
	int num;
	Wire();
	Wire(int num_);
	Wire(Coord c1, Coord c2, int num);
	Coord OtherHeadCoord(Coord c_this);
	Coord C1();
	Coord C2();
	void SetCoord(Coord c1_, Coord c2_);
};

struct DConn{
	Coord c1, c2;
	int num;
	DConn();
	DConn(int num_);
	DConn(Coord c1, Coord c2, int num);
	Coord OtherHeadCoord(Coord c_this);
	Coord C1();
	Coord C2();
	void SetCoord(Coord c1_, Coord c2_);
	void GetNodes(vector<Coord> &nodes);
};

class Connection{
public:
	Connection();
	Connection(int from_, int to_);
	int from, to;
};

struct Foot{
	int number;
	unsigned int x, y;
	string name;
};

class Footprint{
private:
	unsigned int width, height;
	int maxfootnum;
	vector<Foot> foots, rotatedfoots;
	vector< vector<Contentblock> > contentblocks, rotatedcontentblocks;
	bool rotate; //false = normaali, true = ylösalaisin
public:
	Footprint();
	void Allocate(unsigned int w, unsigned int h);
	bool AddFoot(unsigned int x, unsigned int y, int number, string name);
	bool AddComponentBlock(unsigned int x, unsigned int y);
	unsigned int Width();
	unsigned int Height();
	int FootCount();
	int MaxFootNum();
	Foot GetFoot(int i);
	Foot GetFootByNumber(int n);
	vector<Foot> Foots();
	vector< vector<Contentblock> > Contentblocks();
	bool HasAdjacentFeet();
	void SetRotate(bool r);
	bool GetRotate();
};

class Part{
private:
	string name;
	Footprint footprint;
	Coord coords;
	bool locked;
public:
	void SetName(string n);
	string Name();
	void SetFootprint(Footprint fp);
	Footprint * GetFootprint();
	void SetCoord(Coord coords);
	Coord GetCoord();
	Part();
	void SetLocked(bool locked_);
	bool Locked();
};

extern vector<Part> SortPartsByFootCount(vector<Part> parts0);

class WirePart{
private:
	string name, f1name, f2name;
	int length, footn1, footn2, maxfootnum;
	Coord c1, c2;
public:
	void SetName(string n);
	string Name();
	void SetLength(int l);
	int Length();
	void SetFootNums(int n1, int n2);
	void SetFootNames(string f1n, string f2n);
	int FootNum1();
	int FootNum2();
	string FootName1();
	string FootName2();
	int MaxFootNum();
	void SetCoord(Coord c1_, Coord c2_);
	Coord C1();
	Coord C2();
	Coord OtherHeadCoord(Coord c_this);
	WirePart();
	WirePart(int l, int f1, int f2);
	bool HalfDefined();
};


#endif

